feat!: replace Abiword with LibreOffice and add DOCX export#7539
feat!: replace Abiword with LibreOffice and add DOCX export#7539JohnMcLear wants to merge 3 commits intodevelopfrom
Conversation
The Abiword converter is dropped. Abiword's DOCX export is weak and the project is niche on modern platforms; LibreOffice (soffice) is the common deployment path and now serves as the sole converter backend. DOCX is added as an export format and becomes the new target for the "Microsoft Word" UI button. The /export/doc URL still works for legacy API consumers. BREAKING CHANGE: The 'abiword' setting, the INSTALL_ABIWORD Dockerfile build arg, the abiwordAvailable clientVar, and the #importmessageabiword UI element (with locale key pad.importExport.abiword.innerHTML) are removed. Deployments relying on Abiword must configure 'soffice' instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review Summary by QodoReplace Abiword with LibreOffice and add DOCX export support
WalkthroughsDescription• Replace Abiword converter with LibreOffice as sole backend • Add DOCX export format; Word button now downloads DOCX • Remove Abiword configuration, settings, and UI elements • Simplify export/import handler logic by eliminating dual-converter paths • Update documentation and Docker configuration for LibreOffice only Diagramflowchart LR
A["Abiword Converter"] -->|removed| B["LibreOffice Only"]
C["Export Formats<br/>pdf, doc, txt, html, odt"] -->|add docx| D["Export Formats<br/>pdf, doc, docx, txt, html, odt"]
E["Word Button<br/>/export/doc"] -->|changed to| F["Word Button<br/>/export/docx"]
G["Settings Config<br/>abiword + soffice"] -->|simplify to| H["Settings Config<br/>soffice only"]
File Changes1. src/tests/backend/specs/api/importexportGetPost.ts
|
Code Review by Qodo
1. doc export still enabled
|
| const types = ['pdf', 'doc', 'docx', 'txt', 'html', 'odt', 'etherpad']; | ||
| // send a 404 if we don't support this filetype | ||
| if (types.indexOf(req.params.type) === -1) { | ||
| return next(); | ||
| } | ||
|
|
||
| // if abiword is disabled, and this is a format we only support with abiword, output a message | ||
| // if soffice is disabled, and this is a format we only support with soffice, output a message | ||
| if (exportAvailable() === 'no' && | ||
| ['odt', 'pdf', 'doc'].indexOf(req.params.type) !== -1) { | ||
| ['odt', 'pdf', 'doc', 'docx'].indexOf(req.params.type) !== -1) { |
There was a problem hiding this comment.
1. doc export still enabled 📎 Requirement gap ≡ Correctness
The export route still allows doc, so the system continues to expose/produce legacy DOC output instead of fully replacing it with DOCX. This violates the requirement to replace DOC with DOCX for the supported converter path(s).
Agent Prompt
## Issue description
The backend still supports `GET .../export/doc`, which means legacy DOC output is still exposed/produced, conflicting with the requirement to replace DOC with DOCX.
## Issue Context
The UI now uses `/export/docx`, but the server route allowlist still includes `doc` and the export handler writes the output using `.${type}`.
## Fix Focus Areas
- src/node/hooks/express/importexport.ts[31-39]
- src/node/handler/ExportHandler.ts[98-108]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| // hide stuff thats not avaible if soffice is disabled | ||
| if (clientVars.exportAvailable === 'no') { | ||
| $('#exportworda').remove(); | ||
| $('#exportpdfa').remove(); | ||
| $('#exportopena').remove(); | ||
|
|
||
| $('#importmessageabiword').show(); | ||
| } else if (clientVars.exportAvailable === 'withoutPDF') { | ||
| $('#exportpdfa').remove(); | ||
|
|
||
| $('#exportworda').attr('href', `${padRootPath}/export/doc`); | ||
| $('#exportworda').attr('href', `${padRootPath}/export/docx`); | ||
| $('#exportopena').attr('href', `${padRootPath}/export/odt`); | ||
|
|
||
| $('#importexport').css({height: '142px'}); | ||
| $('#importexportline').css({height: '142px'}); | ||
| } else { | ||
| $('#exportworda').attr('href', `${padRootPath}/export/doc`); | ||
| $('#exportworda').attr('href', `${padRootPath}/export/docx`); | ||
| $('#exportpdfa').attr('href', `${padRootPath}/export/pdf`); | ||
| $('#exportopena').attr('href', `${padRootPath}/export/odt`); |
There was a problem hiding this comment.
2. docx export lacks flag 📘 Rule violation ☼ Reliability
DOCX export is newly enabled in both the server allowlist and the UI without any feature flag or disabled-by-default toggle. This violates the requirement that new features be behind a feature flag with the old behavior preserved when disabled.
Agent Prompt
## Issue description
DOCX export is introduced/enabled without a feature flag and changes existing behavior (the Word button now downloads DOCX).
## Issue Context
Compliance requires new features to be behind a flag, disabled by default, and to preserve the old execution path when disabled.
## Fix Focus Areas
- src/static/js/pad_impexp.ts[147-164]
- src/node/hooks/express/importexport.ts[31-46]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| let converter:any = null; | ||
| let exportExtension = 'htm'; | ||
|
|
||
| // load abiword only if it is enabled and if soffice is disabled | ||
| if (settings.abiword != null && settings.soffice == null) { | ||
| converter = require('../utils/Abiword'); | ||
| } | ||
|
|
||
| // load soffice only if it is enabled | ||
| if (settings.soffice != null) { | ||
| converter = require('../utils/LibreOffice'); |
There was a problem hiding this comment.
3. abiword removed without warn 📘 Rule violation ⚙ Maintainability
Abiword import/export support is removed outright (config + runtime converter path), but there is no explicit deprecation period behavior that emits a WARN explaining the upcoming removal. This violates the feature-removal deprecation requirement and increases upgrade risk for existing deployments.
Agent Prompt
## Issue description
Abiword support was removed without an explicit deprecation mechanism and dedicated WARN messaging to guide users before removal.
## Issue Context
Compliance requires a deprecation phase that emits a WARN stating the feature will be removed in a future version. Consider temporarily accepting `abiword` config with a WARN and either continuing to support it for one release cycle or mapping it to the new supported path.
## Fix Focus Areas
- src/node/handler/ImportHandler.ts[59-66]
- settings.json.template[338-345]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
@copilot address qodos concerns and fix the PR |
- Add `docxExport: true` setting to opt out of DOCX (use legacy DOC) - Pass `docxExport` to client via clientVars - Use `docxExport` flag in pad_impexp.ts for Word button format - Emit a specific WARN when deprecated `abiword` config is detected - Update settings.json.template and settings.json.docker with docxExport - Add docxExport to ClientVarPayload type in SocketIOMessage.ts Agent-Logs-Url: https://github.com/ether/etherpad/sessions/9afc5291-73b2-4b66-b028-feed39e7056f Co-authored-by: JohnMcLear <220864+JohnMcLear@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ether/etherpad/sessions/9afc5291-73b2-4b66-b028-feed39e7056f Co-authored-by: JohnMcLear <220864+JohnMcLear@users.noreply.github.com>
Addressed all three Qodos concerns in commits d012f90 and 226c476:
|
Summary
.docxas an export format; the "Microsoft Word" UI button now downloads DOCX/export/docstill works for API consumersCloses #4805.
Rationale
Abiword's DOCX output is experimental and the project is effectively Linux-only (Windows 2.8.6 / macOS 2.4 are abandoned). Most deployments already use soffice via
INSTALL_SOFFICE. Dropping Abiword collapses a forked code path, removes an apt dependency, simplifiesexportAvailable()/ExportHandler/ImportHandler, and lets us cleanly add DOCX — which soffice produces directly from HTML.What changed
Removed:
src/node/utils/Abiword.tssettings.abiwordconfig +abiwordAvailable()+ the Settings.ts fs.exists checkINSTALL_ABIWORDarg +abiword abiword-plugin-commandapk install inDockerfileabiwordentry insettings.json.templateandsettings.json.dockerabiwordAvailableclientVar inPadMessageHandlerandSocketIOMessage#importmessageabiwordelement inpad.html/ui/pad.html, matching CSS inpopup_import_export.cssandcolibris/.../import-export.csspad.importExport.abiword.innerHTMLlocale key across 83 locale filesimportexportGetPost.ts/src/bin/abiword.exefrom.gitignoredoc/docker.mdanddoc/docker.adocAdded:
'docx'in both the export allowlist and the converter-required list inimportexport.tssrc/tests/backend/specs/api/importexportGetPost.ts(exports from scratch, and from imported DOCX)/export/docxKept:
.docas a valid export type on the backend (API-compatible).docand.docxas valid import types (unchanged)Breaking change
Deployments currently using
"abiword": "/usr/bin/abiword"must switch to"soffice": "/usr/bin/soffice". TheINSTALL_ABIWORD=trueDocker build arg is removed — useINSTALL_SOFFICE=true.Test plan
pnpm run ts-checkpassesmocha tests/backend/specs/api/importexportGetPost.ts— 56 passing, 10 pending (soffice-dependent, skipped in local env without LibreOffice), 2 failing (pre-existing on develop:rev test1 is 403/rev test1 results in 500, unrelated to this change — error body serialization issue incheckValidRevpath)mocha tests/backend/specs/export.ts— 1 passing.docxthat opens in LibreOffice / Word / Google Docs🤖 Generated with Claude Code